package com.member.mp.web;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.member.common.core.domain.R;
import com.member.common.core.page.PageResult;
import com.member.common.core.page.TableDataInfo;
import com.member.common.enums.BizUserStatusEnum;
import com.member.mp.aop.DistributeLock;
import com.member.mp.web.user.SupperController;
import com.member.shop.domain.*;
import com.member.shop.dto.RechargeSurplusDto;
import com.member.shop.dto.RechargeSurplusPayDto;
import com.member.shop.service.ISysBizRechargeService;
import com.member.shop.service.ISysBizRechargeUserService;
import com.member.shop.service.ISysBizUserSurplusDetailsService;
import com.member.shop.vo.RechargePayVo;
import com.member.shop.vo.SurplusDetailsVo;
import com.member.shop.vo.SurplusVo;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 【充值余额】控制器
 *
 * @author wangxin
 * @version 1.0
 * @date Mon Jul 03 22:06:51 CST 2024
 **/
@RestController
@RequestMapping("/wx/surplus")
@Slf4j
@Api(value = "余额接口", tags = {"余额接口"})
public class SurplusController extends SupperController {

    @Resource
    private ISysBizRechargeService sysBizRechargeService;
    @Resource
    private ISysBizUserSurplusDetailsService sysBizUserSurplusDetailsService;
    @Resource
    private ISysBizRechargeUserService sysBizRechargeUserService;

    /**
     * 查询充值套餐和余额
     *
     * @return 充值列表
     */
    @GetMapping("/querySurplus")
    public R<SurplusVo> querySurplus() {
        SysBizUser loginUser = getLoginUser();
        Long userId = loginUser.getId();
        Long tenantId = loginUser.getTenantId();
        SurplusVo surplusVo = sysBizRechargeService.querySurplus(userId, tenantId);
        return R.ok(surplusVo);
    }

    /**
     * 查询充值套餐是否存在
     *
     * @return 查询充值套餐是否存在
     */
    @GetMapping("/querySurplusStatus/{id}")
    public R<Boolean> querySurplusStatus(@PathVariable Integer id) {
        LambdaQueryWrapper<SysBizRecharge> sysBizRechargeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysBizRechargeLambdaQueryWrapper.eq(SysBizRecharge::getId, id);
        sysBizRechargeLambdaQueryWrapper.eq(SysBizRecharge::getTenantId, getTenantId());
        sysBizRechargeLambdaQueryWrapper.eq(SysBizRecharge::getDisplayed, BizUserStatusEnum.OK.getKey());
        List<SysBizRecharge> sysBizRecharges = sysBizRechargeService.selectSysBizRechargeList(sysBizRechargeLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(sysBizRecharges)) {
            return R.ok(false);
        } else {
            return R.ok(true);
        }
    }

    /**
     * 充值余额
     *
     * @param rechargeSurplusDto 充值余额
     * @return 支付参数
     */
    @DistributeLock(prefix = "SURPLUS", cacheKey = "SURPLUS:LOCK:", appendUserId = true, lockTime = 10)
    @PostMapping("/rechargeSurplus")
    public R<SysBizRechargeUser> rechargeSurplus(@RequestBody RechargeSurplusDto rechargeSurplusDto) throws WxPayException {
        if (rechargeSurplusDto == null || (rechargeSurplusDto.getRechargePrice() == null && rechargeSurplusDto.getRechargeId() == null)) {
            return R.fail("参数异常");
        }
        if (rechargeSurplusDto.getRechargePrice() != null && rechargeSurplusDto.getRechargePrice().compareTo(BigDecimal.ZERO) <= 0) {
            return R.fail("充值金额不能为0");
        }
        SysBizRechargeUser sysBizRechargeUser = sysBizRechargeService.rechargeSurplus(rechargeSurplusDto, getUserId());
        return R.ok(sysBizRechargeUser);
    }

    /**
     * 支付充值订单
     *
     * @param rechargeSurplusPayDto 参数
     * @return 支付参数
     */
    @PostMapping("/paymentRecharge")
    public R<RechargePayVo> paymentRecharge(@RequestBody @Validated RechargeSurplusPayDto rechargeSurplusPayDto) throws WxPayException {
        SysBizRechargeUser sysBizRechargeUser = sysBizRechargeUserService.getById(rechargeSurplusPayDto.getId());
        if (sysBizRechargeUser == null) {
            return R.fail("充值订单不存在");
        }
        if (sysBizRechargeUser.getPaymentStatus() == 1) {
            return R.fail("充值订单已支付");
        }
        if (sysBizRechargeUser.getPaymentStatus() == 2) {
            return R.fail("支付时间已过，请重新下单");
        }
        RechargePayVo payVo = sysBizRechargeService.paymentRecharge(rechargeSurplusPayDto);
        return R.ok(payVo);
    }

    /**
     * 查询余额明细
     *
     * @param type 0 充值记录 1 消费记录
     * @return 支付参数
     */
    @GetMapping("/querySurplusDetails")
    public R<PageResult<SurplusDetailsVo>> querySurplusDetails(@RequestParam(name = "type",required = false) Integer type,
                                                               @RequestParam(name = "startDate",required = false) String startDate) {
        startPage();
        LambdaQueryWrapper<SysBizUserSurplusDetails> queryWrapper = new LambdaQueryWrapper<>();
        if (type != null) {
            queryWrapper.eq(SysBizUserSurplusDetails::getType, type);
        }
        queryWrapper.eq(SysBizUserSurplusDetails::getTenantId, getTenantId());
        queryWrapper.eq(SysBizUserSurplusDetails::getUserId, getUserId());
        // 处理年月范围查询
        if (StringUtils.isNotEmpty(startDate)) {
            // 解析年月字符串，格式：yyyy-MM
            YearMonth yearMonth = YearMonth.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM"));
            // 生成当月第一天 00:00:00
            LocalDateTime startDateTime = yearMonth.atDay(1).atStartOfDay();
            // 生成当月最后一天 23:59:59
            LocalDateTime endDateTime = yearMonth.atEndOfMonth().atTime(23, 59, 59);
            queryWrapper.between(SysBizUserSurplusDetails::getCreateTime, startDateTime, endDateTime);
        }

        queryWrapper.orderByDesc(SysBizUserSurplusDetails::getId);
        List<SysBizUserSurplusDetails> sysBizUserSurplusDetails = sysBizUserSurplusDetailsService.list(queryWrapper);
        TableDataInfo dataTable = getDataTable(sysBizUserSurplusDetails);
        List<?> rows = dataTable.getRows();
        ArrayList<SurplusDetailsVo> item = new ArrayList<>();
        for (Object row : rows) {
            SysBizUserSurplusDetails surplusDetails = (SysBizUserSurplusDetails) row;
            SurplusDetailsVo target = new SurplusDetailsVo();
            BeanUtils.copyProperties(surplusDetails, target);
            item.add(target);
        }
        return R.ok(new PageResult<>(dataTable.getTotal(), item));
    }

}
